<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useMessage } from 'naive-ui'
import logger from '../utils/logger'

export interface LogItem {
  id: number
  timestamp: string
  type: 'info' | 'success' | 'error' | 'warning' | 'debug'
  message: string
  details?: string
}

const message = useMessage()

// 日志最大保留数量
const MAX_LOG_COUNT = 500

// 日志数据
const logs = ref<LogItem[]>([])
// 过滤模式：all(全部) | simple(简洁)
const filterMode = ref<'all' | 'simple'>('all')
// 排序顺序：asc(正序-旧到新) | desc(倒序-新到旧)
const sortOrder = ref<'asc' | 'desc'>('desc')
// 日志ID计数器
let logIdCounter = 0

// 过滤和排序后的日志
const filteredLogs = computed(() => {
  // 先过滤
  let result = logs.value
  if (filterMode.value === 'simple') {
    // 简洁模式：只显示 success 和 error，不显示 debug
    result = logs.value.filter((log) => log.type === 'success' || log.type === 'error')
  } else {
    // 全部模式：不显示 debug 日志
    result = logs.value.filter((log) => log.type !== 'debug')
  }

  // 再排序
  if (sortOrder.value === 'asc') {
    // 正序：旧到新（ID 从小到大）
    return [...result].reverse()
  }
  // 倒序：新到旧（默认顺序）
  return result
})

// 添加日志
const addLog = (type: LogItem['type'], msg: string, details?: string): void => {
  const now = new Date()
  const timestamp = `[${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}]`

  logs.value.unshift({
    id: logIdCounter++,
    timestamp,
    type,
    message: msg,
    details
  })

  // 限制日志数量，超过最大值时移除最旧的日志
  if (logs.value.length > MAX_LOG_COUNT) {
    logs.value.pop() // 移除最后一条（最旧的）
  }
}

// 清空日志
const clearLogs = (): void => {
  logs.value = []
  message.success('日志已清空')
}

// 复制日志
const copyLogs = async (): Promise<void> => {
  if (filteredLogs.value.length === 0) {
    message.warning('暂无日志可复制')
    return
  }

  const logText = filteredLogs.value
    .map((log) => {
      const prefix = `${log.timestamp} [${log.type.toUpperCase()}]`
      return log.details ? `${prefix} ${log.message}\n${log.details}` : `${prefix} ${log.message}`
    })
    .join('\n')

  try {
    await navigator.clipboard.writeText(logText)
    message.success('日志已复制到剪贴板')
  } catch {
    message.error('复制失败')
  }
}

// 加载配置
const loadConfig = async (): Promise<void> => {
  try {
    const config = (await window.api.getAppConfig('log')) as {
      filterMode?: 'all' | 'simple'
      sortOrder?: 'asc' | 'desc'
    }
    if (config) {
      if (config.filterMode) {
        filterMode.value = config.filterMode
      }
      if (config.sortOrder) {
        sortOrder.value = config.sortOrder
      }
      logger.info('日志面板配置加载成功', {
        filterMode: config.filterMode,
        sortOrder: config.sortOrder
      })
    }
  } catch (error) {
    logger.error('加载日志配置失败', { error: error as Error })
  }
}

// 保存配置
const saveConfig = async (): Promise<void> => {
  try {
    await window.api.saveAppConfig('log', {
      filterMode: filterMode.value,
      sortOrder: sortOrder.value
    })
    logger.info('日志面板配置保存成功', {
      filterMode: filterMode.value,
      sortOrder: sortOrder.value
    })
  } catch (error) {
    logger.error('保存日志配置失败', { error: error as Error })
  }
}

// 切换过滤模式
const toggleFilterMode = (): void => {
  filterMode.value = filterMode.value === 'all' ? 'simple' : 'all'
}

// 切换排序顺序
const toggleSortOrder = (): void => {
  sortOrder.value = sortOrder.value === 'desc' ? 'asc' : 'desc'
}

// 监听配置变化，自动保存
watch([filterMode, sortOrder], () => {
  saveConfig()
})

// 环境级别过滤
const shouldShowLog = (level: string): boolean => {
  const isDev = import.meta.env.DEV
  const minLevel = isDev ? 'debug' : 'info'
  const levelPriority = { debug: 0, info: 1, warn: 2, error: 3, success: 1 }
  return (
    (levelPriority[level as keyof typeof levelPriority] ?? 1) >=
    (levelPriority[minLevel as keyof typeof levelPriority] ?? 1)
  )
}

// 监听主进程日志
const handleMainLog = (
  _event: unknown,
  logData: { level: string; message: string; process: string }
): void => {
  if (shouldShowLog(logData.level)) {
    addLog(logData.level as LogItem['type'], `[${logData.process}] ${logData.message}`)
  }
}

// 监听渲染进程日志
const handleRendererLog = (event: Event): void => {
  const customEvent = event as CustomEvent<{ level: string; message: string }>
  const { level, message } = customEvent.detail
  if (shouldShowLog(level)) {
    addLog(level as LogItem['type'], `[RENDERER] ${message}`)
  }
}

// 获取日志类型对应的图标
const getLogIcon = (type: LogItem['type']): string => {
  const iconMap = {
    info: 'i-carbon-information-filled',
    success: 'i-carbon-checkmark-filled',
    error: 'i-carbon-close-filled',
    warning: 'i-carbon-warning-filled',
    debug: 'i-carbon-debug'
  }
  return iconMap[type]
}

// 获取日志类型对应的颜色
const getLogColor = (type: LogItem['type']): string => {
  const colorMap = {
    info: 'text-blue-600',
    success: 'text-green-600',
    error: 'text-red-600',
    warning: 'text-orange-600',
    debug: 'text-gray-500'
  }
  return colorMap[type]
}

// 组件挂载时加载配置和设置监听
onMounted(() => {
  loadConfig()

  // 监听主进程日志
  window.electron?.ipcRenderer?.on('log-message', handleMainLog)

  // 监听渲染进程日志
  window.addEventListener('renderer-log', handleRendererLog)
})

// 组件卸载时清理监听
onUnmounted(() => {
  window.electron?.ipcRenderer?.removeListener('log-message', handleMainLog)
  window.removeEventListener('renderer-log', handleRendererLog)
})

// 暴露方法给父组件使用
defineExpose({
  addLog
})
</script>

<template>
  <div class="flex flex-col h-full bg-gray-50 rounded-lg border border-gray-200">
    <!-- 头部工具栏 - 固定高度约 8% -->
    <div
      class="flex items-center justify-between px-2 py-1.5 border-b border-gray-200 bg-white rounded-t-lg flex-shrink-0"
    >
      <div class="flex items-center gap-1.5">
        <span class="i-carbon-chart-line text-lg text-gray-700"></span>
        <h3 class="text-sm font-semibold">执行日志</h3>
        <n-tag v-if="logs.length > 0" type="info" size="tiny">
          {{ logs.length }} / {{ MAX_LOG_COUNT }} 条
        </n-tag>
      </div>
      <div class="flex gap-1.5">
        <n-button size="tiny" @click="toggleFilterMode">
          <template #icon>
            <span
              :class="filterMode === 'simple' ? 'i-carbon-filter-edit' : 'i-carbon-filter'"
              class="text-xs"
            ></span>
          </template>
          {{ filterMode === 'simple' ? '简洁模式' : '全部模式' }}
        </n-button>
        <n-button size="tiny" @click="toggleSortOrder">
          <template #icon>
            <span
              :class="sortOrder === 'desc' ? 'i-carbon-sort-descending' : 'i-carbon-sort-ascending'"
              class="text-xs"
            ></span>
          </template>
          {{ sortOrder === 'desc' ? '倒序' : '正序' }}
        </n-button>
        <n-button size="tiny" @click="copyLogs">
          <template #icon>
            <span class="i-carbon-copy text-xs"></span>
          </template>
          复制
        </n-button>
        <n-button size="tiny" @click="clearLogs">
          <template #icon>
            <span class="i-carbon-trash-can text-xs"></span>
          </template>
          清空
        </n-button>
      </div>
    </div>

    <!-- 日志内容区域 - 自适应占据剩余空间 -->
    <div
      class="flex-1 overflow-y-auto px-2 py-1.5 font-mono text-xs scrollbar-hide min-h-0 bg-white"
    >
      <!-- 空状态 -->
      <div
        v-if="filteredLogs.length === 0"
        class="h-full flex items-center justify-center text-gray-400"
      >
        <div class="text-center">
          <span class="i-carbon-document-blank text-3xl block mb-1.5"></span>
          <p class="text-xs">{{ logs.length === 0 ? '暂无日志' : '当前过滤模式下无日志' }}</p>
        </div>
      </div>

      <!-- 日志列表 - 紧凑显示 -->
      <div v-for="log in filteredLogs" :key="log.id" class="flex items-start gap-1.5 py-0.5">
        <span
          :class="[getLogIcon(log.type), getLogColor(log.type), 'text-sm flex-shrink-0']"
        ></span>
        <span class="text-gray-500 flex-shrink-0">{{ log.timestamp }}</span>
        <span :class="['font-semibold uppercase flex-shrink-0', getLogColor(log.type)]">
          {{ log.type }}
        </span>
        <span class="text-gray-800">
          {{ log.message }}
          <span v-if="log.details" class="text-gray-600">{{ log.details }}</span>
        </span>
      </div>
    </div>
  </div>
</template>
